from flask import Blueprint, request, current_app, g, url_for
from util.result import Result
import base64
import uuid
import os
from datetime import datetime

# 创建文件上传蓝图
api_bp = Blueprint('file', __name__)

# 1. 上传图片文件接口
@api_bp.route('/file/upload', methods=['POST'])
def file_upload():
    try:
        # 1. 接收前端传递的 JSON 数据（必须包含 base64 字段）
        data = request.get_json()
        if not data:
            return Result.error("请求数据不能为空")

        # 2. 验证核心字段：base64 编码是否存在
        base64_str = data.get('base64')
        if not base64_str or not str(base64_str).strip():
            return Result.error("base64 编码是必填项")

        # 3. 处理 Base64 编码（去除前缀，如 "data:image/png;base64,"）
        # 前端可能传递带前缀或纯编码，这里兼容两种情况
        if 'base64,' in base64_str:
            # 截取前缀后的纯编码部分
            base64_data = base64_str.split('base64,')[-1].strip()
        else:
            base64_data = base64_str.strip()

        # 4. 验证 Base64 编码有效性（避免无效编码导致解码报错）
        try:
            # 解码 Base64 为二进制数据
            image_bytes = base64.b64decode(base64_data, validate=True)
        except (base64.binascii.Error, ValueError):
            return Result.error("Base64 编码无效，请检查图片格式")

        # 5. 定义图片保存路径（static 目录下，建议按日期分文件夹，避免文件过多）
        # 5.1 基础路径：项目根目录/static/images/（需确保目录存在）
        base_save_dir = os.path.join(current_app.root_path, 'static', 'images')
        # 5.2 按当前日期创建子目录，便于管理
        date_dir = datetime.now().strftime('%Y%m%d')
        full_save_dir = os.path.join(base_save_dir, date_dir)
        # 5.3 若目录不存在则创建（递归创建多级目录）
        os.makedirs(full_save_dir, exist_ok=True)

        # 6. 生成唯一图片名称（UUID + 后缀，后缀从 Base64 前缀推断或默认 png）
        # 6.1 推断图片后缀（从原始 Base64 前缀提取，如 data:image/png;base64 → png）
        image_suffix = 'png'  # 默认后缀
        if 'data:image/' in base64_str:
            # 提取前缀中的格式（如 "data:image/jpeg;base64," → jpeg）
            suffix_match = base64_str.split('data:image/')[1].split(';')[0]
            # 兼容常见格式（jpeg 统一为 jpg，避免后缀不一致）
            if suffix_match in ['jpeg', 'jpg', 'png']:
                image_suffix = 'jpg' if suffix_match == 'jpeg' else suffix_match

        # 6.2 生成 UUID 唯一文件名（如 550e8400-e29b-41d4-a716-446655440000.jpg）
        uuid_filename = f"{uuid.uuid4()}.{image_suffix}"

        # 7. 保存图片到指定路径
        full_save_path = os.path.join(full_save_dir, uuid_filename)
        with open(full_save_path, 'wb') as f:
            f.write(image_bytes)

        # 8. 生成图片的访问路径（使用 Flask 的 url_for 生成绝对路径，便于前端直接访问）
        # 路径格式：/static/images/20240910/550e8400-e29b-41d4-a716-446655440000.jpg
        relative_path = os.path.join('static', 'images', date_dir, uuid_filename)
        # 生成可直接访问的 URL（如 http://localhost:5000/static/images/20240910/xxx.jpg）
        host_url=current_app.config.get('SERVER_HOST',request.host_url)

        image_url = host_url + relative_path  # 带域名的绝对URL

        # 9. 返回成功结果（包含图片路径和文件名）
        return Result.success(data={
            "image_url": image_url,          # 图片访问URL（前端可直接用 img 标签 src 引用）
            "relative_path": relative_path,  # 图片相对路径（如需存储到数据库，建议存此路径）
            "filename": uuid_filename        # 图片文件名（可选，用于前端展示）
        }, msg="图片上传成功")

    except Exception as e:
        # 异常捕获（如文件写入失败、权限不足等）
        current_app.logger.error(f"图片上传异常: {str(e)}", exc_info=True)  # 打印详细堆栈，便于排查
        return Result.error("图片上传失败，请稍后重试")

